home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 4
/
Apprentice-Release4.iso
/
Languages
/
Mops 2.7
/
Mops source
/
Module source
/
pasmMod.txt
< prev
next >
Encoding:
Amiga
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Text File
|
1995-11-30
|
25.4 KB
|
1,059 lines
|
[
TEXT/MSET
]
(* *********
\ PowerPC 601 Assembler
\ Copyright 1993-1994 Xan Gregg All Rights Reserved
\ Permission is granted for internal distribution by Creative Solutions, Inc.
\ Permission also granted for Mops distribution. Mops mods made by
\ Mike Hore.
This is a basic PowerPC 601 assembler. It uses a Forth-like syntax,
but the mnemonics and operand order is usually preserved. The exception
is the branching instructions, which will be seldom used anyway since
words like IF, and WHILE, are available. Often, duplicating identical
parameters is not required, such as if the source and destination
registers are the same.
Examples Motorola Syntax Forth Syntax
add. r1, r1, r2 r1 r2 add.,
cmpi cr1, r3, 25 cr1 r3 25 cmpi,
crnor crb1, crb1, crb4 crb1 crb4 crnor,
--ALSO-- cr0 bGT cr1 bLT crnor,
lfd fr1, 20(r2) fr1 20 r2 lfd,
mtspr MQ, r3 MQ r3 mtspr,
blt target target lt bc,
blt- target hint target lt bc,
bdnzl cr2, target cr2 target dnz bcl,
Non-PowerPC instructions are not included.
***** *)
decimal
\ First, the Mops version of the utility words, and a few
\ others we need as well:
: DeferrErr true abort" DEFERRed word not set" ;
: DEFER ['] deferrErr vect ;
: IS postpone -> ; immediate
: TOKEN@ @abs ;
: TOKEN! reloc! ;
: TOKEN, reloc, ;
: NOT 0= ;
: SCALE ( val cnt -- val' )
dup 0< IF negate >> ELSE << THEN ;
: HEX# postpone $ ; immediate
: Lo2 $ 0000FFFF postpone literal postpone and ; immediate
: Hi2 $ FFFF0000 postpone literal postpone and ; immediate
: Hi2Lo 16 >> ;
: ERROR" postpone abort" ; immediate
: EVAL i >r evaluate r> -> i ; \ have to save & restore I till bug fixed
: OFF false swap ! ;
: ON true swap ! ;
: BLWORD Mword ;
: TOKEN.FOR state IF postpone ['] ELSE ' THEN ; immediate
: RANGE within? ;
: SIMM? ( n -- n b ) \ is this a signed immediate (16 bit) value?
-32768 32767 within? ;
: UIMM? ( n -- n b )
0 65535 within? ;
: PSTRCPY ( addr1\addr2 -- )
over c@ 1+ cmove ;
: HOLD$ \ ( addr len -- )
dup --> hld
hld swap cmove ;
: ALIGN4 \ pad with zero bytes till DP is 4-byte aligned
DP
4 reserve \ just to ensure pad bytes are zero
3 + $ fffffffc and -> DP ;
: #ALIGN4 \ ( n -- n' )
3 + $ fffffffc and ;
: code_align PPC?
IF CDP 4 erase CDP #align4 -> CDP
ELSE align4
THEN ;
\ defer codeHere ' here is codeHere
\ defer commaInstr ' , is commaInstr
: codeHere PPC? IF CDP ELSE DP THEN ;
\ note: code, (defined in Base) already looks at PPC? and does the right thing.
0 value opInstr \ instruction being assembled
: OR>INSTR ( n -- ) opInstr or -> opInstr ;
: ScaleOR>INSTR ( n\b -- ) scale or>instr ;
: >RaField ( n -- ) 16 scaleOr>Instr ;
: >RbField ( n -- ) 11 scaleOr>Instr ;
: >RcField ( n -- ) 6 scaleOr>Instr ;
: >RdField ( n -- ) 21 scaleOr>Instr ;
: >RsField ( n -- ) 21 scaleOr>Instr ;
: >LField ( n -- ) 21 scaleOr>Instr ;
: >TOField ( n -- ) 21 scaleOr>Instr ;
: >SRField ( n -- ) 16 scaleOr>Instr ;
: >SHField ( n -- ) 11 scaleOr>Instr ;
: >NBField ( n -- ) 11 scaleOr>Instr ;
: >MBField ( n -- ) 6 scaleOr>Instr ;
: >MEField ( n -- ) 1 scaleOr>Instr ;
: >DispField ( n -- ) Lo2 or>Instr ;
: >ImmField ( n -- ) Lo2 or>Instr ;
hex# fa970000 constant RegisterID
hex# fa870000 constant FRegisterID
hex# fa770000 constant CRegisterID
hex# fa670000 constant CBRegisterID
hex# fa570000 constant SPRegisterID
hex# fa470000 constant ModifierID
hex# fa370000 constant ConditionID
: MODIFIER ( value -- | create a register constant)
ModifierID or constant ;
: MODIFIER? ( [value] -- [value\true] | [false] )
depth 0 > IF dup Hi2 ModifierID = ELSE false THEN ;
: REGISTER ( value -- | create a register constant)
RegisterID or constant ;
: REGISTER# ( value -- n )
Lo2 ;
: REGISTER? ( [value] -- [value\true] | [false] )
depth 0 > IF dup Hi2 RegisterID = ELSE false THEN ;
: REGISTER#? ( [value] -- [value\true] | [false] )
register? dup if swap register# swap then ;
: NEEDREGISTER ( [value] -- )
register? not error" EXPECTED A REGISTER" ;
: NEEDREGISTER# ( [value] -- n )
register#? not error" EXPECTED A REGISTER" ;
: DECLAREREGISTERS ( -- )
32 0 DO
i 0 <# 2dup #s " register R" hold$ 2drop #s #> eval
LOOP ;
: FREGISTER ( value -- | create a register constant)
FRegisterID or constant ;
: FREGISTER? ( [value] -- [value\true] | [false] )
depth 0 > IF dup Hi2 FRegisterID = ELSE false THEN ;
: FREGISTER#? ( [value] -- [value\true] | [false] )
fregister? dup if swap register# swap then ;
: NEEDFREGISTER ( [value] -- )
fregister? not error" EXPECTED A FREGISTER" ;
: NEEDFREGISTER# ( [value] -- )
fregister#? not error" EXPECTED A FREGISTER" ;
: DECLAREFREGISTERS ( -- )
32 0 DO
i 0 <# 2dup #s " fregister FR" hold$ 2drop #s #> eval
LOOP ;
: CREGISTER ( value -- | create a register constant)
CRegisterID or constant ;
: CREGISTER? ( [value] -- [value\true] | [false] )
depth 0 > IF dup Hi2 CRegisterID = ELSE false THEN ;
: CREGISTER#? ( [value] -- [value\true] | [false] )
cregister? dup if swap register# swap then ;
: NEEDCREGISTER ( [value] -- )
cregister? not error" EXPECTED A CREGISTER" ;
: DECLARECREGISTERS ( -- )
8 0 DO
i 0 <# 2dup #s " cregister CR" hold$ 2drop #s #> eval
LOOP ;
: CBREGISTER ( value -- | create a register constant)
CBRegisterID or constant ;
: CBREGISTER? ( [value] -- [value\true] | [false] )
depth 0 > IF dup Hi2 CBRegisterID = ELSE false THEN ;
: CBREGISTER#? ( [value] -- [value\true] | [false] )
cbregister? dup if swap register# swap then ;
: NEEDCBREGISTER ( [value] -- )
cbregister? not error" EXPECTED A CBREGISTER" ;
: DECLARECBREGISTERS ( -- )
32 0 DO
i 0 <# 2dup #s " cbregister CRB" hold$ 2drop #s #> eval
LOOP ;
: SPREGISTER ( value -- | create a register constant)
dup 31 and 5 scale swap -5 scale or SPRegisterID or constant ;
: SPREGISTER? ( [value] -- [value\true] | [false] )
depth 0 > IF dup Hi2 SPRegisterID = ELSE false THEN ;
: NEEDSPREGISTER ( [value] -- )
spregister? not error" EXPECTED An SPREGISTER" ;
: CONDITION ( value -- | create a condition constant)
conditionID or
constant ;
: CONDITION? ( [value] -- [value\true] | [false] )
depth 0 > IF dup Hi2 conditionID = ELSE false THEN ;
: NEEDCONDITION ( [value] -- )
condition? not error" EXPECTED A CONDITION" ;
: MODIFIERVALUE ( value -- n )
Lo2 ;
: CONDITIONVALUE ( value -- n )
Lo2 ;
\ branchHint is a one-shot set by 'hint' and cleared by the next branch instr.
variable branchHint
branchHint off
\ ASSEMBLER.WORDS
: hint branchHint on ;
DeclareRegisters
DeclareFRegisters
DeclareCRegisters
DeclareCBRegisters
0 SPRegister MQ
1 SPRegister XER
4 SPRegister RTCU
5 SPRegister RTCL
6 SPRegister DEC
8 SPRegister LR
9 SPRegister CTR
: bLT ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* CBRegisterID or ;
: bGT ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* 1+ CBRegisterID or ;
: bEQ ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* 2+ CBRegisterID or ;
: bSO ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* 3+ CBRegisterID or ;
create condArea 10 allot
: COND$ condArea count ;
: COND3 ( bit#\pos? -- )
blword condArea pstrcpy
IF hex# 180 ELSE hex# 080 THEN or
dup 0 <# cond$ hold$ " condition " hold$ #s #> eval
hex# f7f and
dup ( 1+) 0 <# cond$ hold$ " condition dnz" hold$ #s #> eval
hex# 040 or 0 <# cond$ hold$ " condition dz" hold$ #s #> eval
;
0 1 cond3 lt
1 1 cond3 gt
2 1 cond3 eq
3 1 cond3 so
4 1 cond3 un
0 0 cond3 nl
1 0 cond3 ng
2 0 cond3 ne
3 0 cond3 ns
4 0 cond3 nu
0 0 cond3 ge
1 0 cond3 le
hex# 200 condition dnz
hex# 240 condition dz
hex# 280 condition tr
1 modifier LONG \ for cmp instruction
0 modifier WD \ for cmp instruction ** note - can't use WORD
\ LOCAL.WORDS
\ GetDAB ( dreg\[areg]\[breg]\tester -- | inserts D, A, and B regs into opInstr)
\ A and B are optional
: GetDAB ( d a b ) { tester \ d a b -- } \ inserts D, A, and B regs into opInstr)
\ 0 0 0 locals| d a b tester |
tester execute not error" expected a register"
-> b
tester execute not IF \ 1 register: d,d,d
b -> a
a -> d
ELSE
-> a
tester execute IF \ 3 registers: d,a,b
-> d
ELSE \ 2 registers: d,d,a
a -> d
THEN
THEN
d >RdField a >RaField b >RbField ;
: GETRDAB ( dreg\[areg]\[breg] -- )
token.for register#? getDAB ;
: GETFRDAB ( dreg\[areg]\[breg] -- )
token.for fregister#? getDAB ;
: getCRBdab ( dreg\[areg]\[breg] -- )
token.for cbregister#? getDAB ;
: ?SIMM ( n -- )
simm? nip not error" EXPECTED A SIMM" ;
: ?UIMM ( n -- )
0 65535 range nip not error" EXPECTED A UIMM" ;
\ GETDAIMM ( dreg\[areg]\simm\tester -- | inserts D, and A regs and SIMM into opInstr)
\ A is optional
: GETDAIMM ( d [a] ) { simm tester \ d a -- }
\ 0 0 locals| d a tester simm |
simm tester execute
register#? not error" expected a register"
-> a
register#? not IF a THEN -> d
d >RdField a >RaField simm >ImmField ;
: GETRDASIMM ( dreg\[areg]\simm -- )
token.for ?simm GetDAImm ;
: GETRDAUIMM ( dreg\[areg]\simm -- )
token.for ?uimm GetDAImm ;
: GETRDAIMM ( dreg\[areg]\imm -- )
token.for drop GetDAImm ;
\ GETDA ( dreg\[areg]\tester -- | inserts D and A regs into opInstr)
\ A is optional
\ 0 0 locals| d a tester |
: GETDA ( d [a] ) { tester \ d a -- }
tester execute not error" expected a register"
-> a
tester execute not IF a THEN -> d
d >RdField a >RaField ;
: GETRDA ( dreg\[areg] -- )
token.for register#? GetDA ;
: GETRASBIMM ( [areg]\sreg\[breg]|[imm] -- )
register#? IF >RbField ELSE >ImmField THEN
needRegister# dup >R >RsField
register#? IF R> drop ELSE R> THEN >RaField ;
: GETRASB ( [areg]\sreg\breg -- )
needRegister# >RbField
needRegister# dup >R >RsField
register#? IF R> drop ELSE R> THEN >RaField ;
: GETRASIMM ( [areg]\sreg\imm -- )
dup ?uimm
>ImmField
needRegister# dup >R >RsField
register#? IF R> drop ELSE R> THEN >RaField ;
: GETCRLAB ( [crReg]\[L]\areg\breg -- )
needRegister# >RbField
needRegister# >RaField
modifier? IF ModifierValue >LField THEN
cregister#? if 23 ScaleOR>INSTR then ;
: GETCRLAIMM ( [crReg]\[L]\areg\imm -- )
dup ?simm
>ImmField
needRegister# >RaField
modifier? IF ModifierValue >LField THEN
cregister#? if 23 ScaleOR>INSTR then ;
: GETCRFAB ( [crReg]\areg\breg -- )
needFRegister# >RbField
needFRegister# >RaField
cregister#? if 23 ScaleOR>INSTR then ;
: GETRAB ( areg\breg -- )
needRegister# >RbField
needRegister# >RaField ;
: GETRAS ( areg\[sreg] -- ) { \ s -- }
\ needRegister# locals| S |
needRegister# -> s
s >RsField
register#? not IF s THEN >RaField ;
: GETFRDB ( dfreg\[bfreg] -- ) { \ b -- }
\ needFRegister# locals| B |
needFRegister# -> b
b >RbField
fregister#? not IF b THEN >RdField ;
: GetNull ( -- )
;
: GetRsab ( [sreg]\areg\breg -- )
needRegister# >RbField
needRegister# dup >R >RaField
register#? IF R> drop ELSE R> THEN >RsField ;
: GetCRds ( CRd\CRs -- )
needCRegister register# 18 ScaleOR>INSTR
needCRegister register# 23 ScaleOR>INSTR ;
: GetCRd ( CRd -- )
needCRegister register# 23 ScaleOR>INSTR ;
: GetRd ( Rd -- )
needRegister# >RdField ;
: GetRdSPR ( Rd\SPR -- )
needSPRegister register# 11 ScaleOR>INSTR
needRegister# >RdField ;
: GetRdSR ( Rd\SR -- )
>SRField
needRegister# >RdField ;
: GetRdb ( [Rd]\Rb -- )
needRegister# dup >R >RbField
register#? IF R> drop ELSE R> THEN >RdField ;
: getCRMRs ( CRM\Rs -- )
needRegister# >RsField
255 and 12 ScaleOR>INSTR ; \ bug fixed 25-Aug-94 via msg from xg
: getCRBd ( CRBd -- )
needCBRegister register# >RdField ;
: getFMFrb ( FM\FRb -- )
needFRegister# >RbField
255 and 17 ScaleOR>INSTR ;
: getCRdBImm ( CRd\Imm -- )
15 and 12 ScaleOR>INSTR
needCRegister register# 23 ScaleOR>INSTR ;
: GetRs ( sreg -- )
needRegister# >RsField ;
: GetSPRRs ( SPR\Rs -- )
needRegister# >RsField
needSPRegister register# 11 ScaleOR>INSTR ;
: getSRRs ( SR\Rs -- )
needRegister# >RsField
15 and >SRField ;
: getRsb ( [Rs]\Rb -- )
needRegister# dup >R >RbField
register#? IF R> drop ELSE R> THEN >RsField ;
: getRasSHMBME ( [Ra]\Rs\SH\MB\ME -- )
31 and >MEField
31 and >MBField
31 and >SHField
needRegister# dup >R >RsField
register#? IF R> drop ELSE R> THEN >RaField ;
: getRasbMBME ( [Ra]\Rs\Rb\MB\ME -- )
31 and >MEField
31 and >MBField
needRegister# >SHField
needRegister# dup >R >RsField
register#? IF R> drop ELSE R> THEN >RaField ;
: getRasSH ( [Ra]\Rs\SH -- )
31 and >SHField
needRegister# dup >R >RsField
register#? IF R> drop ELSE R> THEN >RaField ;
: getRsaDisp ( Rs\[disp\]Ra -- )
needRegister# >RaField
simm? if >DispField then
needRegister# >RsField ;
: getFRsRaDisp ( FRs\[disp\]Ra -- )
needRegister# >RaField
simm? if >DispField then
needFRegister# >RsField ;
: getFRsRab ( FRs\Ra\Rb -- )
needRegister# >RbField
needRegister# >RaField
needFRegister# >RsField ;
: getRsaNB ( [Ra]\Rs\NB -- )
31 and >NBField
needRegister# dup >R >RaField
register#? IF R> drop ELSE R> THEN >RsField ;
: getRb ( Rb -- )
needRegister# >RbField ;
: getTORab ( TO\Ra\Rb -- )
needRegister# >RbField
needRegister# >RaField
31 and >TOField ;
: getTORaSImm ( TO\Ra\Simm -- )
dup ?simm >ImmField
needRegister# >RaField
31 and >TOField ;
: getFRdRaDisp ( FRd\[disp\]Ra -- )
needRegister# >RaField
simm? if >DispField then
needFRegister# >RdField ;
: getFRdRab ( FRd\Ra\Rb -- )
needRegister# >RbField
needRegister# >RaField
needFRegister# >RdField ;
: getRdaDisp ( Rd\[disp\]Ra -- )
needRegister# >RaField
simm? if >DispField then
needRegister# >RdField ;
: getRdaNB ( Rd\Ra\nb -- )
31 and >NBField
needRegister# >RaField
needRegister# >RdField ;
: getFRdacb ( [FRd]\FRa\FRc\FRb -- )
needFRegister# >RbField
needFRegister# >RcField
needFRegister# dup >R >RaField
fregister#? IF R> drop ELSE R> THEN >RdField ;
: getFRdac ( [FRd]\FRa\FRc -- )
needFRegister# >RcField
needFRegister# dup >R >RaField
fregister#? IF R> drop ELSE R> THEN >RdField ;
: checkAddress ( addr\numBits -- addr )
over 3 and error" INVALID ADDRESS - NOT MULTIPLE OF 4"
1 swap 1- scale dup negate swap 1-
range not error" INVALID ADDRESS - OUT OF RANGE" ;
: ?hint \ set the branch bit if requested by the one-shot
branchHint @ if
branchHint off
1 21 scaleOr>Instr
then ;
: getAbsAddr
26 checkAddress
\ hex# 3FF,FFFC and or>Instr ?hint ;
hex# 3FFFFFC and or>Instr ?hint ;
: getRelAddr ( addr -- )
codehere - getAbsAddr ;
: getBOBI ( [crreg]\[cond] -- )
condition? IF
conditionValue 16 ScaleOr>Instr
ELSE
hex# 280 16 ScaleOr>Instr \ branch always if no condition
THEN
cregister#? IF
18 ScaleOr>Instr
THEN ?hint ;
: getUncondBOBI ( -- )
hex# 280 16 ScaleOr>Instr ; \ branch always
: getBOBIAddr ( addr\[cond]\[cond] -- )
condition? IF
conditionValue 16 ScaleOr>Instr
ELSE
hex# 280 16 ScaleOr>Instr \ branch always if no condition
THEN
opInstr 2 and not IF codehere - THEN
13 checkAddress hex# fffc and or>Instr
cregister#? IF
18 ScaleOr>Instr
THEN ?hint ;
\ -------------------------------------------------------
: OP ( asm instruction defining word )
\ find dup -found >R
\ create ( opcode1\opcode2 -- ) swap 26 scale or , R> token,
Mword find NIF ." aauuggghhh!!" abort THEN
>r
<builds ( opcode1\opcode2 -- ) swap 26 scale or , r> token,
does> ( pfa -- | lays down instruction )
dup @ -> opInstr
4+ token@ execute
opInstr code, ;
create OPCODEArea 10 allot
: OPCODE$ opcodeArea count ;
create GETTERAREA 20 allot
: GETTER$ getterArea count ;
: DEFININGTEXT ( n1 n2 -- 0 | called from inside <# #> )
\ mh's note - we take care of converting the numbers to doubles here.
0 swap 0
opcode$ hold$ BL hold getter$ hold$ " OP " hold$ #S BL hold 2drop #s ;
\ : evaluate.string ( addr -- )
\ cr dup count type
\ evaluate.string
\ 40 >col here 14 .r ;
: OPo. ( opcode1\opcode2 -- super asm instruction defining word )
blword getterArea pstrcpy
blword opcodeArea pstrcpy
2* 2dup <# " ," hold$ definingText #> eval
2dup 1+ <# " .," hold$ definingText #> eval
2dup 1024 + <# " o," hold$ definingText #> eval
1025 + <# " o.," hold$ definingText #> eval
;
: OP. ( opcode1\opcode2 -- super asm instruction defining word )
blword getterArea pstrcpy
blword opcodeArea pstrcpy
2* 2dup <# " ," hold$ definingText #> eval
1+ <# " .," hold$ definingText #> eval
;
\ ASSEMBLER.WORDS
31 266 OPo. getRdab add
31 10 OPo. getRdab addc
31 138 OPo. getRdab adde
14 0 OP getRdaSimm addi,
12 0 OP getRdaSimm addic,
13 0 OP getRdaSimm addic.,
15 0 OP getRdaSimm addis,
31 234 OPo. getRda addme
31 202 OPo. getRda addze
31 28 OP. getRasb and
31 60 OP. getRasb andc
28 0 OP getRasImm andi.,
29 0 OP getRasImm andis.,
( ** branch instructions ** )
18 0 OP getRelAddr b,
18 2 OP getAbsAddr ba,
18 1 OP getRelAddr bl,
18 3 OP getAbsAddr bla,
16 0 OP getBOBIAddr bc,
16 2 OP getBOBIAddr bca,
16 1 OP getBOBIAddr bcl,
16 3 OP getBOBIAddr bcla,
19 1056 OP getBOBI bcctr,
19 1057 OP getBOBI bcctrl,
19 32 OP getBOBI bclr,
19 33 OP getBOBI bclrl,
19 1056 OP getUncondBOBI bctr,
19 1057 OP getUncondBOBI bctrl,
19 32 OP getUncondBOBI blr,
19 33 OP getUncondBOBI blrl,
31 0 OP getCrLAB cmp,
11 0 OP getCrLAImm cmpi,
31 64 OP getCrLAB cmpl,
10 0 OP getCrLAImm cmpli,
31 26 OP. getRas cntlzw
19 514 OP getCRBdab crand,
19 258 OP getCRBdab crandc,
19 578 OP getCRBdab creqv,
19 450 OP getCRBdab crnand,
19 66 OP getCRBdab crnor,
19 898 OP getCRBdab cror,
19 834 OP getCRBdab crorc,
19 386 OP getCRBdab crxor,
31 172 OP getRab dcbf,
31 940 OP getRab dcbi,
31 108 OP getRab dcbst,
31 556 OP getRab dcbt,
31 492 OP getRab dcbtst,
31 2028 OP getRab dcbz,
31 491 OPo. getRdab divw
31 459 OPo. getRdab divwu
31 620 OP getRdab eciwx,
31 876 OP getRdab ecowx,
31 1708 OP getNull eieio,
31 284 OP. getRasb eqv
31 954 OP. getRas extsb
31 922 OP. getRas extsh
63 264 OP. getFRdb fabs
63 21 OP. getFRdab fadd
59 21 OP. getFRdab fadds
63 64 OP getCRFab fcmpo,
63 0 OP getCRFab fcmpu,
63 14 OP. getFRdb fctiw
63 15 OP. getFRdb fctiwz
63 18 OP. getFRdab fdiv
59 18 OP. getFRdab fdivs
63 29 OP. getFRdacb fmadd
59 29 OP. getFRdacb fmadds
63 72 OP. getFRdb fmr
59 28 OP. getFRdacb fmsub
59 28 OP. getFRdacb fmsubs
63 25 OP. getFRdac fmul
59 25 OP. getFRdac fmuls
63 136 OP. getFRdb fnabs
63 40 OP. getFRdb fneg
63 31 OP. getFRdacb fnmadd
59 31 OP. getFRdacb fnmadds
63 30 OP. getFRdacb fnmsub
59 30 OP. getFRdacb fnmsubs
63 12 OP. getFRdb frsp
63 20 OP. getFRdab fsub
59 20 OP. getFRdab fsubs
31 1964 OP getRab icbi,
19 300 OP getNull isync,
34 0 OP getRdaDisp lbz,
35 0 OP getRdaDisp lbzu,
31 238 OP getRdab lbzux,
31 174 OP getRdab lbzx,
50 0 OP getFRdRaDisp lfd,
51 0 OP getFRdRaDisp lfdu,
31 1262 OP getFRdRab lfdux,
31 1198 OP getFRdRab lfdx,
48 0 OP getFRdRaDisp lfs,
49 0 OP getFRdRaDisp lfsu,
31 1134 OP getFRdRab lfsux,
31 1070 OP getFRdRab lfsx,
31 1198 OP getFRdRab lfdx,
42 0 OP getRdaDisp lha,
43 0 OP getRdaDisp lhau,
31 750 OP getRdab lhaux,
31 686 OP getRdab lhax,
31 1580 OP getRdab lhbrx,
40 0 OP getRdaDisp lhz,
41 0 OP getRdaDisp lhzu,
31 622 OP getRdab lhzux,
31 558 OP getRdab lhzx,
46 0 OP getRdaDisp lmw,
31 1194 OP getRdaNb lswi,
31 1066 OP getRdab lswx,
31 40 OP getRdab lwarx,
31 1068 OP getRdab lwbrx,
32 0 OP getRdaDisp lwz,
33 0 OP getRdaDisp lwzu,
31 110 OP getRdab lwzux,
31 46 OP getRdab lwzx,
19 0 OP getCRds mcrf,
63 128 OP getCRds mcrfs,
31 1024 OP getCRd mcrxr,
31 38 OP getRd mfcr,
63 583 OP. getRd mffs
31 166 OP getRd mfmsr,
31 678 OP getRdSPR mfspr,
31 1190 OP getRdSR mfsr,
31 1318 OP getRdb mfsrin,
31 288 OP getCRMRs mtcrf,
63 70 OP. getCRBd mtfsb0
63 38 OP. getCRBd mtfsb1
31 711 OP. getFMFrb mtfsf
63 134 OP. getCRdBImm mtfsfi
31 292 OP getRs mtmsr,
31 934 OP getSPRRs mtspr,
31 420 OP getSRRs mtsr,
31 484 OP getRsb mtsrin,
31 75 OP. getRdab mulhw
31 11 OP. getRdab mulhwu
31 235 OPo. getRdab mullw
7 0 OP getRdaSImm mulli,
31 476 OP. getRasb nand
31 104 OPo. getRda neg
31 124 OP. getRasb nor
31 444 OP. getRasb or
31 412 OP. getRasb orc
24 0 OP getRasImm ori,
25 0 OP getRasImm oris,
19 100 OP getNull rfi,
20 0 OP. getRasSHMBME rlwimi
21 0 OP. getRasSHMBME rlwinm
23 0 OP. getRasbMBME rlwnm
17 2 OP getNull sc,
31 24 OP. getRasb slw
\ 31 794OP. getRasb srad
31 792 OP. getRasb sraw
31 824 OP. getRasSH srawi
\ 31 539OP. getRasb srd
31 536 OP. getRasb srw
38 0 OP getRsaDisp stb,
39 0 OP getRsaDisp stbu,
31 494 OP getRsab stbux,
31 430 OP getRsab stbx,
54 0 OP getFRsRaDisp stfd,
55 0 OP getFRsRaDisp stfdu,
31 1518 OP getFRsRab stfdux,
31 1454 OP getFRsRab stfdx,
52 0 OP getFRsRaDisp stfs,
53 0 OP getFRsRaDisp stfsu,
31 1390 OP getFRsRab stfsux,
31 1326 OP getFRsRab stfsx,
44 0 OP getRsaDisp sth,
31 1836 OP getRsab sthbrx,
45 0 OP getRsaDisp sthu,
31 878 OP getRsab sthux,
31 814 OP getRsab sthx,
47 0 OP getRsaDisp stmw,
31 1450 OP getRsaNB stswi,
31 1322 OP getRsab stswx,
36 0 OP getRsaDisp stw,
31 1324 OP getRsab stwbrx,
31 301 OP getRsab stwcx.,
37 0 OP getRsaDisp stwu,
31 366 OP getRsab stwux,
31 302 OP getRsab stwx,
31 40 OPo. getRdab subf
31 8 OPo. getRdab subfc
31 136 OPo. getRdab subfe
08 0 OP getRdaSImm subfic,
31 232 OPo. getRda subfme
31 200 OPo. getRda subfze
31 1196 OP getNull sync,
31 612 OP getRb tlbie,
31 8 OP getTORab tw,
03 0 OP getTORaSImm twi,
31 316 OP. getRasb xor
26 0 OP getRasImm xori,
27 0 OP getRasImm xoris,
\ Assembler Macro Definitions
\ Branching macros
: bcPatch ( instr addr\dest addr )
over - 13 checkAddress
hex# 0000FFFC and over @ hex# FFFF0003 and or swap ! ;
: bPatch ( instr addr\dest addr )
over - 24 checkAddress
hex# 03FFFFFC and over @ hex# FC000003 and or swap ! ;
: invertCondition ( condition -- condition' )
dup hex# 200 and 0= IF \ make sure it uses conditions
hex# 100 xor \ flip BO[1]
THEN ;
: if, ( condition -- addr\2 )
invertCondition codehere swap bc,
codehere 4- 2 ;
: else, ( addr\2 -- addr\3 )
2 ?pairs codehere 4+ bcPatch
codehere b,
codehere 4- 3 ;
: then, ( [addr\2] or [addr\3] -- )
dup 3 = IF
3 ?pairs codehere bpatch
ELSE
2 ?pairs codehere bcPatch
THEN ;
: begin, ( -- addr\1 )
codehere 1 ;
: while, ( condition -- addr\4 )
if, 2+ ;
: bcBackwhiles ( [addr\4]* -- )
begin
dup 4 =
while
drop codehere 4+ bcPatch
repeat ;
: again, ( addr\1[\addr\4]* -- )
bcBackwhiles
1 ?pairs
b, ;
: repeat, ( addr\1[\addr\4]* -- )
again, ;
: until, ( addr\1[\addr\4]*\condition -- )
>R bcBackwhiles
1 ?pairs
R> invertCondition bc, ;
\ these are simplified mnemonics from PowerPC manual
: nop, ( -- ) r0 r0 r0 ori, ;
: li, ( rA\SIMM -- | load immediate ) r0 swap addi, ;
: lis, ( rA\SIMM -- | load immediate shifted ) r0 swap addis, ;
: lli, ( rA\SLIMM -- | load long immediate )
dup 0=
IF li,
ELSE
2dup extend dup \ rA\SLIMM\rA\simm\simm
IF li,
dup Hi2Lo swap hex# 8000 and IF \ sign bit set in lo 16 bits?
1+ Lo2
THEN
dup IF extend addis, ELSE 2drop THEN
ELSE \ lo half is 0
2drop Hi2Lo extend lis,
THEN
THEN ;
(* ***
old versions:
: li, ( rA\SIMM -- | load immediate ) r0 swap addi, ;
: lis, ( rA\SIMM -- | load immediate shifted ) r0 swap addis, ;
: lli, ( rA\SLIMM -- | load long immediate )
2dup extend li,
dup Hi2Lo swap hex# 8000 and IF \ sign bit set in lo 16 bits?
1+ Lo2
THEN
?dup IF extend addis, ELSE drop THEN ;
*** *)
: lui, ( rA\SIMM -- | load immediate ) lli, ;
: la, ( rD\SIMM\rA -- | load address ) swap addi, ;
: move, ( rA\rS -- ) dup or, ;
: move., ( rA\rS -- ) dup or., ;
: not, ( rA\rS -- ) dup nor, ;
: not., ( rA\rS -- ) dup nor., ;
: subi, ( rA\SIMM -- ) negate addi, ;
: slwi, ( rA\rS\n -- ) 0 over 31 swap - rlwinm, ;
: srwi, ( rA\rS\n -- ) 32 over - swap 31 rlwimi, ;
: mtlr, ( rA -- ) lr swap mtspr, ;
: mflr, ( rA -- ) lr mfspr, ;
: mtctr, ( rA -- ) ctr swap mtspr, ;
: mfctr, ( rA -- ) ctr mfspr, ;
: clr, ( rA -- ) dup dup subf, ;
\ Some Forth macros
: rOSSP r1 ; \ Operating system stack pointer
: rTOC r2 ; \ table of contents pointer
: rTOS r13 ; \ top of data stack value
: rDSP r14 ; \ data stack pointer
: rRSP r15 ; \ return stack pointer
: rUP r16 ; \ user area pointer
: rLFP r17 ; \ local frame pointer
: rCBP r18 ; \ code base pointer
: rDBP r19 ; \ data base pointer
: rDoLimit r20 ;
: rDoIndex r21 ;
\ Note: R11, R12, CR6, & CR7 are designated as scratch registers by Apple
: rX r11 ;
: rY r12 ;
: crX cr6 ;
: crY cr7 ;
\ r0 is also scratch but must be used carefully as it is special in some
\ instructions
: put, ( reg -- ) rtos swap move, ;
: pushtos, ( -- ) rtos -4 rdsp stwu, ;
: push, ( reg -- ) pushtos, put, ;
: get, ( reg -- ) rtos move, ;
: poptos, ( -- ) rtos 0 rdsp lwz, rdsp 4 addi, ;
: pop, ( reg -- ) get, poptos, ;
: tst, ( reg -- ) 0 cmpi, ;
: rts, ( -- ) bclr, ;
: next, ( address interpreter )
rts, ;
decimal
false value pasm_done?
: FIND_IN_PASM \ ( s255 -- cfa true | -- s255 false )
find: pasmMod ;
: ENTERCODE \ begin assembly outside of a colon definition
lock: pasmMod
['] find_in_pasm -> extraFind \ look up words in pasm first. Exclude
\ locals and class stuff for the duration
false -> pasm_done?
code_align
;
\ :PPC_CODE begins a code definition. We set up a header specifying
\ no named parms/locals and 2 results. This means that the top 2 stack
\ cells will be in r4 and r3 on both entry and exit, which keeps things
\ simple.
: :PPC_CODE
ppc_header
$ BE00 codeW, \ handler code for PPC colon defns
$ 0200 codeW, \ no named parms/locals, 2 results
entercode
BEGIN
topfile -> source-ID (Frefill) IF interpret THEN
pasm_done?
UNTIL ;
: ;PPC_CODE
0 -> extraFind
unlock: pasmMod
true -> pasm_done?
?exec reveal
;
// disAsm